
#include <vector>
#include <list>
#include <deque>
#include <mutex>
#include <condition_variable>
#include <iostream>
using namespace std;
#ifndef SYNC_QUEUE_4_HPP
#define SYNC_QUEUE_4_HPP
#if 0
namespace tulun
{
    const int MaxTaskCount = 500; // 定义队列最大任务数量
    // 模板类 SyncQueue，用于实现同步队列
    template <class T> // T 在这里表示任务类型
    class SyncQueue
    {
    private:
        // std::vector<std::list<T>> m_queue;
        std::vector<std::deque<T>> m_queue;
        size_t m_bucketSize;                // vector.resize(16);
        size_t m_maxSize;                   // vector[0].deque.size();
        mutable std::mutex m_mutex;         // 互斥锁，用于保证线程安全
        std::condition_variable m_notEmpty; // 条件变量，用于通知消费者队列非空
        std::condition_variable m_notFull;  // 条件变量，用于通知生产者队列非满
        std::condition_variable m_waitStop; // 条件变量，用于等待队列停止
        size_t m_waitTime;                  // 等待时间，单位为毫秒
        bool m_needStop;                    // 标志位，用于表示队列是否需要停止

        bool IsEmpty(const int index) const // 判断队列是否为空
        {
            // std::lock_guard<std::mutex> lock(m_mutex);
            bool empty = m_queue[index].empty(); // 此处没有加锁，因为调用此函数前已经加锁
            if (empty)
            { // 若队列为空，可输出调试信息
              //  cerr << "m_queue empty wait... " << endl;
            }
            return empty;
        }
        bool IsFull(const int index) const // 判断队列是否已满
        {
            // std::lock_guard<std::mutex> lock(m_mutex);
            bool full = m_queue[index].size() >= m_maxSize; // 此处没有加锁，因为调用此函数前已经加锁
            if (full)
            {
                // 若队列已满，可输出调试信息
                cerr << "m_queue[" << index << " ] full wait ..." << endl;
                //  cerr << "m_maxSize: " << m_maxSize << endl;
                //  cerr << "m_queue.size(): " << m_queue.size() << endl;
            }
            return full;
        }
        // 向队列中添加任务的模板函数
        template <class F>
        int Add(F &&task, const int index) // 可接受左值和右值引用
        {
            std::unique_lock<std::mutex> lock(m_mutex); // 加锁，保证线程安全
            int ret = -1;
            // 等待队列非满或需要停止，等待时间为m_waitTime
            bool tag = m_notFull.wait_for(lock,
                                          std::chrono::milliseconds(m_waitTime),
                                          [this, &index]() -> bool
                                          {
                                              return (!IsFull(index) || m_needStop);
                                          });
            if (m_needStop)
            {
                ret = -1; // 若队列需要停止，返回-1
            }
            else if (!tag)
            {
                ret = -2; // 若等待超时且队列仍满，返回-2
            }
            else
            {
                m_queue[index].push_back(std::forward<F>(task)); // 将任务添加到队列末尾
                ret = 0;
            }
            m_notEmpty.notify_all(); // 通知所有等待队列非空的线程
            return ret;
        }

    public:
        // 构造函数，初始化队列的最大任务数量和等待时间
        SyncQueue(int bucketsize = 16, int maxsize = MaxTaskCount, const size_t timeout = 10) // ms
            : m_bucketSize(bucketsize),                                                       // 16 * 500
              m_maxSize(maxsize),
              m_needStop(false),
              m_waitTime(timeout)
        {
            m_queue.resize(m_bucketSize);
        }
        ~SyncQueue() // 析构函数，确保队列停止
        {
            if (!m_needStop)
            {
                Stop();
            }
        }
        // 禁用拷贝构造函数和赋值运算符
        SyncQueue(const SyncQueue &) = delete;
        SyncQueue &operator=(const SyncQueue &) = delete;

        // 向队列中添加左值任务
        int Put(const T &task, const int index)
        {
            return Add(task, index);
        }
        // 向队列中添加右值任务
        int Put(T &&task, const int index)
        {
            return Add(std::forward<T>(task), index);
        }

        // 从队列中取出所有任务
        int Take(std::deque<T> &queue, const int index)
        {
            std::unique_lock<std::mutex> lock(m_mutex);
            int ret = -1;
            // 等待队列非空或需要停止，等待时间为m_waitTime
            bool tag = m_notEmpty.wait_for(lock,
                                           std::chrono::milliseconds(m_waitTime),
                                           [this, &index]() -> bool
                                           {
                                               return (m_needStop || !IsEmpty(index));
                                           });
            if (m_needStop)
            {
                ret = -1; // 若队列需要停止，返回-1
            }
            else if (!tag)
            {
                ret = -3; // 若等待超时且队列仍空，返回-3
            }
            else
            {
                queue = std::move(m_queue[index]); // 将队列中的所有任务移动到参数队列中
                ret = 0;
            }
            m_notFull.notify_all(); // 通知所有等待队列非满的线程
            return ret;
        }
        int Take(T &task, const int index)
        {
            std::unique_lock<std::mutex> lock(m_mutex);
            int ret = -1;
            // 等待队列非空或需要停止，等待时间为m_waitTime
            bool tag = m_notEmpty.wait_for(lock,
                                           std::chrono::milliseconds(m_waitTime),
                                           [this, &index]() -> bool
                                           {
                                               return (m_needStop || !IsEmpty(index));
                                           });
            if (m_needStop)
            {
                ret = -1; // 若队列需要停止，返回-1
            }
            else if (!tag)
            {
                ret = -3; // 若等待超时且队列仍空，返回-3
            }
            else
            {
                task = m_queue[index].front();
                m_queue[index].pop_front();
                ret = 0;
            }
            m_notFull.notify_all(); // 通知所有等待队列非满的线程
            return ret;
        }
        // 停止队列
        void Stop()
        {
            {
                std::unique_lock<std::mutex> lock(m_mutex);
                for (int i = 0; i < m_bucketSize; ++i)
                {
                    while (!m_needStop && IsEmpty(i))
                    {
                        m_notFull.wait_for(lock, std::chrono::seconds(m_waitTime));
                    }
                }
                m_needStop = true;
            }
            // 通知所有等待队列非满和非空的线程
            m_notFull.notify_all();
            m_notEmpty.notify_all();
        }
        // 等待队列清空后停止
        void WaitQueueEmptyStop()
        {
#if 0
            cout << "WaitQueueEmptyStop() " << endl;
            std::unique_lock<std::mutex> locker(m_mutex);
            cout << " locker(m_mutex)" << endl;
            while (!IsEmpty()) // 等待队列清空
            {
                cout << "SysncQueue:: wait_for: IsEmpty():" << !IsEmpty();
                m_waitStop.wait_for(locker, std::chrono::milliseconds(m_waitTime));
            }
            cout << " SyncQueue:: m_queue:size() " << m_queue.size() << endl;
            m_needStop = true;
            // 通知所有等待队列非满和非空的线程
            m_notFull.notify_all();
            m_notEmpty.notify_all();
#endif
        }
        bool Empty(const int index) const
        {
            std::lock_guard<std::mutex> lock(m_mutex);
            return m_queue[index].empty();
        }
        bool Full(const int index) const
        {
            std::lock_guard<std::mutex> lock(m_mutex);
            return m_queue[index].size() >= m_maxSize;
        }
        // 获取队列当前大小
        size_t Size(const int index) const
        {
            std::lock_guard<std::mutex> lock(m_mutex);
            return m_queue[index].size();
        }
        // 获取队列当前任务数量
        size_t Count(const int index) const
        {
            return m_queue[index].size();
        }
        size_t TaskTotalSize() const
        {
            std::lock_guard<std::mutex> lock(m_mutex);
            size_t sum = 0;
            for (auto &xdeq : m_queue)
            {
                sum += xdeq.size();
            }
            return sum;
        }
        void PrintTaskInfo() const
        {
            std::lock_guard<std::mutex> m_mutex;
            int n = m_queue.size();
            for (int i = 0; i < n; ++i)
            {
                printf("%d 桶中任务的数量 %d \n", i, m_queue[i].size());
            }
            printf("\n-----------------------------\n");
        }
    };
}
#endif
#endif